import { forwardRef, useImperativeHandle, useState } from 'react';

import { useRequest } from 'ahooks';
import {
  Button,
  Divider,
  Drawer,
  DrawerProps,
  Form,
  FormProps,
  Input,
  InputNumber,
  Radio,
  Select,
  Space,
  Switch,
  Typography
} from 'antd';

import Title from '@/components/title';

import { store } from '@/store';

import { noSpaceValidator } from '@/config/rule';
import {
  APIAuthTypeObj,
  APICascadeType,
  APICascadeTypeObj,
  APIDataAuthType,
  APIDataAuthTypeObj,
  APILockType,
  APILockTypeObj,
  APILogLevelObj,
  APIRateLimitModeObj,
  APIRateLimitType,
  APIRateLimitTypeObj,
  APITypeObj
} from '@/enum/api';
import {
  permissionApiCascadeAdd,
  permissionApiCascadeUpdate,
  permissionApiGetTableName
} from '@/services/base/quanxianmokuaihouduanjiekouxinxijiekou';

import { BizObject } from '.';

type EditOpenBaseArgs = {
  /** 成功回调 */
  onSuccess?: () => void;
};

export type EditRef = {
  open: (
    arg:
      | (EditOpenBaseArgs & {
          type: 'edit';
          rowData: BizObject;
        })
      | (EditOpenBaseArgs & {
          type: 'detail';
          rowData: BizObject;
        })
  ) => void;
};

export type DetailProps = {};

const Edit: React.ForwardRefRenderFunction<EditRef, DetailProps> = (_, ref) => {
  const [form] = Form.useForm();
  // 弹窗开启状态
  const [open, setOpen] = useState(false);
  const [args, setArgs] = useState<ArgumentsType<EditRef['open']>[0]>();
  const submit = useRequest(
    async (values: any) => {
      const query = {
        normalField: {
          ...args?.rowData,
          ...values.normalField
        },
        cascadeField: {
          ...args?.rowData,
          ...values.cascadeField
        }
      } as BASE.CascadeUpdatePermissionDto | BASE.CascadeUpdatePermissionDto;

      if (Array.isArray(query.cascadeField.referTableName)) {
        query.cascadeField.referTableName = query.cascadeField.referTableName.join(';');
      }

      if (query.cascadeField.limitFlowConfig) {
        query.cascadeField.limitFlowConfig = JSON.stringify(
          query.cascadeField.limitFlowConfig
        ) as unknown as typeof query.cascadeField.limitFlowConfig;
      }

      if (args?.type === 'edit' && args.rowData) {
        query.id = args.rowData.id;
        query.pid = args.rowData.pid;
      }

      await (args?.type === 'edit'
        ? permissionApiCascadeUpdate(query)
        : permissionApiCascadeAdd(query));

      args?.onSuccess?.();
      setOpen(false);

      store.app?.message.success(args?.type === 'edit' ? '编辑成功' : '新增成功');
    },
    {
      manual: true
    }
  );
  // 数据表
  const tableList = useRequest(async () => {
    const res = await permissionApiGetTableName();

    return res.data;
  });

  useImperativeHandle(ref, () => {
    return {
      open: (arg) => {
        setArgs(arg);
        setOpen(true);
      }
    };
  });

  const onFinish: FormProps['onFinish'] = async (values) => {
    return submit.runAsync(values);
  };

  const onCancel = () => {
    if (submit.loading) {
      store.app?.message.info('正在提交中，请稍后');

      return;
    }

    setOpen(false);
  };

  const afterOpenChange: DrawerProps['afterOpenChange'] = (open) => {
    if (open) {
      // 编辑回填数据
      if ((args?.type === 'edit' || args?.type === 'detail') && args?.rowData) {
        const limitFlowConfig = (() => {
          try {
            if (args.rowData.limitFlowConfig && typeof args.rowData.limitFlowConfig === 'string') {
              return JSON.parse(args.rowData.limitFlowConfig);
            }

            return {};
          } catch (e) {
            return {};
          }
        })();

        // 回填数据
        form.setFieldsValue({
          normalField: {
            ...args.rowData
          },
          cascadeField: {
            ...args.rowData,
            saveLog: args.rowData.saveLog ?? false,
            updateLockType: args.rowData.updateLockType ?? APILockType.不锁定,
            limitFlow: args.rowData.limitFlow ?? APIRateLimitType.关闭,
            isCascade: APICascadeType.不级联,
            referTableName: args.rowData?.referTableName?.split(';').filter(Boolean),
            limitFlowConfig
          }
        });
      } else {
        form.resetFields();
        form.setFieldsValue({
          cascadeField: {
            isCascade: APICascadeType.不级联,
            saveLog: true,
            updateLockType: APILockType.不锁定,
            limitFlow: APIRateLimitType.关闭
          }
        });
      }
    }
  };

  return (
    <Drawer
      title={
        {
          add: '新增接口',
          edit: '编辑接口',
          detail: '接口详情'
        }[args?.type as string]
      }
      width="50%"
      open={open}
      afterOpenChange={afterOpenChange}
      onClose={onCancel}
      footer={
        args?.type === 'detail' ? null : (
          <Space>
            <Button
              type="primary"
              loading={submit.loading}
              disabled={submit.loading}
              onClick={form.submit}
            >
              保存
            </Button>
            <Button onClick={onCancel} disabled={submit.loading}>
              取消
            </Button>
          </Space>
        )
      }
    >
      <Form
        onFinish={onFinish}
        form={form}
        layout="horizontal"
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 14 }}
        labelWrap
      >
        <Title>普通字段</Title>

        {/* 普通字段 */}
        <Form.Item
          label="权限类型"
          name={['normalField', 'permissionType']}
          rules={[
            {
              required: true,
              message: '请选择权限类型'
            }
          ]}
        >
          <Radio.Group>
            {Array.from(APITypeObj).map(([key, value]) => (
              <Radio key={key} value={key}>
                {value.text}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>
        <Form.Item
          label="接口名称"
          name={['normalField', 'permissionName']}
          rules={[
            {
              required: true,
              message: '请输入接口名称'
            }
          ]}
        >
          <Input placeholder="请输入接口名称" allowClear />
        </Form.Item>
        <Form.Item
          label="接口key"
          name={['normalField', 'apiCode']}
          rules={[
            {
              required: true,
              message: '请输入接口key'
            }
          ]}
        >
          <Input placeholder="请输入接口key" allowClear />
        </Form.Item>
        <Form.Item
          label="排序"
          name={['normalField', 'sort']}
          rules={[
            {
              required: true,
              message: '请输入排序'
            }
          ]}
        >
          <InputNumber placeholder="请输入排序" />
        </Form.Item>
        <Form.Item
          label="接口地址"
          name={['normalField', 'url']}
          rules={[
            {
              required: true,
              message: '请输入接口地址'
            }
          ]}
        >
          <Input placeholder="请输入接口地址" allowClear />
        </Form.Item>
        <Form.Item
          label="请求方式"
          name={['normalField', 'requestWay']}
          rules={[
            {
              required: true,
              message: '请输入请求方式'
            }
          ]}
        >
          <Input placeholder="请输入请求方式" allowClear />
        </Form.Item>
        {/* end普通字段 */}

        <Divider />
        <Title>级联字段</Title>
        {/* 级联字段 */}
        <Form.Item label="是否级联更新" name={['cascadeField', 'isCascade']}>
          <Radio.Group>
            {Array.from(APICascadeTypeObj).map(([key, value]) => (
              <Radio key={key} value={key}>
                {value.text}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>

        <Form.Item label="状态" name={['cascadeField', 'status']}>
          <Radio.Group>
            {Array.from(APIAuthTypeObj).map(([key, value]) => (
              <Radio key={key} value={key}>
                {value.text}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>

        <Form.Item
          label="服务名称"
          name={['cascadeField', 'serveName']}
          rules={[
            {
              required: true,
              message: '请输入服务名称'
            },
            {
              validator: noSpaceValidator
            }
          ]}
        >
          <Input placeholder="请输入服务名称" allowClear />
        </Form.Item>

        <Form.Item
          label="日志级别"
          name={['cascadeField', 'logLevel']}
          rules={[
            {
              required: true,
              message: '请选择日志级别'
            }
          ]}
        >
          <Radio.Group>
            {Array.from(APILogLevelObj).map(([key, value]) => (
              <Radio key={key} value={key}>
                {value.text}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>

        <Form.Item
          label="是否保存请求日志"
          name={['cascadeField', 'saveLog']}
          valuePropName="checked"
        >
          <Switch />
        </Form.Item>

        <Form.Item
          label="修改锁定，用于自动更新权限信息时不修改某些权限"
          name={['cascadeField', 'updateLockType']}
        >
          <Radio.Group>
            {Array.from(APILockTypeObj).map(([key, value]) => (
              <Radio key={key} value={key}>
                {value.text}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>

        <Form.Item label="日志说明" name={['cascadeField', 'logExplain']}>
          <Input.TextArea placeholder="请输入日志说明" allowClear />
        </Form.Item>

        <Form.Item label="IP白名单" name={['cascadeField', 'whiteList']}>
          <Input.TextArea placeholder="请输入IP白名单" allowClear />
        </Form.Item>

        <Form.Item label="IP黑名单" name={['cascadeField', 'blackList']}>
          <Input.TextArea placeholder="请输入IP黑名单" allowClear />
        </Form.Item>

        <Form.Item label="数据权限" name={['cascadeField', 'dataPermission']}>
          <Radio.Group>
            {Array.from(APIDataAuthTypeObj).map(([key, value]) => (
              <Radio key={key} value={key}>
                {value.text}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>

        <Form.Item dependencies={[['cascadeField', 'dataPermission']]} noStyle>
          {({ getFieldValue }) => {
            const dataPermission = getFieldValue(['cascadeField', 'dataPermission']);

            if (dataPermission === APIDataAuthType.开启) {
              return (
                <>
                  <Form.Item
                    label="表名"
                    name={['cascadeField', 'referTableName']}
                    rules={[{ required: true, message: '请选择表名' }]}
                  >
                    <Select
                      options={tableList.data?.map((item) => ({ label: item, value: item }))}
                      placeholder="请选择表名"
                      allowClear
                      mode="multiple"
                    />
                  </Form.Item>
                </>
              );
            }

            return null;
          }}
        </Form.Item>

        <Form.Item label="日志说明" name={['cascadeField', 'logExplain']}>
          <Input.TextArea placeholder="请输入日志说明" allowClear />
        </Form.Item>

        <Typography.Title level={5}>接口限流</Typography.Title>

        <Form.Item label="是否开启接口限流" name={['cascadeField', 'limitFlow']}>
          <Radio.Group>
            {Array.from(APIRateLimitTypeObj).map(([key, value]) => (
              <Radio key={key} value={key}>
                {value.text}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>

        <Form.Item dependencies={[['cascadeField', 'limitFlow']]} noStyle>
          {({ getFieldValue }) => {
            const limitFlow = getFieldValue(['cascadeField', 'limitFlow']);

            if (limitFlow === APIRateLimitType.开启) {
              return (
                <>
                  <Form.Item label="限流key" name={['cascadeField', 'limitFlowConfig', 'key']}>
                    <Input.TextArea placeholder="支持使用Spring el表达式来动态获取方法上的参数值,格式类似于#code.id #{#code}" />
                  </Form.Item>
                  <Form.Item
                    label="限流时间,单位秒"
                    name={['cascadeField', 'limitFlowConfig', 'time']}
                  >
                    <InputNumber
                      placeholder="限流时间,单位秒"
                      style={{ width: '100%' }}
                      step={1}
                      min={0}
                    />
                  </Form.Item>
                  <Form.Item label="限流次数" name={['cascadeField', 'limitFlowConfig', 'count']}>
                    <InputNumber
                      placeholder="限流次数"
                      style={{ width: '100%' }}
                      step={1}
                      min={0}
                    />
                  </Form.Item>
                  <Form.Item
                    label="限流类型"
                    name={['cascadeField', 'limitFlowConfig', 'limitType']}
                  >
                    <Radio.Group>
                      {Array.from(APIRateLimitModeObj).map(([key, value]) => (
                        <Radio key={key} value={key}>
                          {value.text}
                        </Radio>
                      ))}
                    </Radio.Group>
                  </Form.Item>
                  <Form.Item
                    label="限流提示信息"
                    name={['cascadeField', 'limitFlowConfig', 'message']}
                  >
                    <Input.TextArea placeholder="限流提示信息" />
                  </Form.Item>
                </>
              );
            }

            return null;
          }}
        </Form.Item>
        {/* end 级联字段 */}
      </Form>
    </Drawer>
  );
};

export default forwardRef(Edit);
